package com.scalar.chiptrack.operations.packingslip.actions;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.operations.packingslip.FinalInventoryData;
import com.scalar.chiptrack.operations.packingslip.dao.FinalInventoryDAO;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.chiptrack.users.User;

public final class FinalInventoryAction extends ChipTrackAction {


	public ActionForward execute (ActionMapping mapping,
							  ActionForm form,
							  HttpServletRequest request,
							  HttpServletResponse response)
							  throws Exception {

		String action = request.getParameter( "action" );
        String isRequestFromTrackingNoPage = (String) request.getParameter("isReqFromTrackingNoPage");
		HttpSession session = request.getSession();


        User user = (User) session.getAttribute( SessionKeys.USER_KEY );

        if ( ( ( isRequestFromTrackingNoPage != null ) && ( isRequestFromTrackingNoPage.equals( "true" ) ) ) ) //when request comes from PS Vendor Interface
        {
            action =  (String) request.getAttribute( "action" );
        }

        if ( user == null )
		{
            request.setAttribute    ( "closeWindowAfterSessionExp", "true" );
            return ( mapping.findForward( "success" ) );
        }

		// SAVE ///////////////////////////////////////////////
		if ( "save".equalsIgnoreCase( action ) )
		{
			// Get inventory data and save it in session
			HashMap errors = new HashMap();
			ArrayList finalInventoryDataList = null;

			try
			{
				finalInventoryDataList = getFinalInventoryDataFromRequest ( request );
			}
			catch( Exception e )
			{
				errors.put ( e.getMessage(), null );
				e.printStackTrace();
			}

			//////// DO NOT SAVE IT HERE ///// SAVE IT WHILE SAVING PACKING SLIP /////////
			//
			// Update balance and shipping fields in inventory_lot table
			//
			//try {
			//    FinalInventoryDAO.updateInventoryLotData (finalInventoryDataList);
			//}
			//catch (ScalarException se) {
			//    se.getRootCause().printStackTrace();
			//    errors.put ("Internal Server", "Could not update balance in the Inventory_Lot table");
			//}
			//
			/////////////////////////////////////////////////////////////////////////////

			if ( errors.isEmpty() == false )
			{
				request.setAttribute ( SessionKeys.ERROR_MESSAGES, errors );
				session.setAttribute ( "FINAL_INVENTORY_ACTION_ERRORS", errors );
				System.out.println( "FINAL_INVENTORY IS HAVING ERRORS" );
				return ( mapping.findForward ( "failure" ) );
			}

			HashMap map = (HashMap) session.getAttribute( SessionKeys.FINAL_INVENTORY_MAP );

            if ( map == null )
			{
				map = new HashMap();
                map.put ( request.getParameter( "lineItemId" ), finalInventoryDataList );
			}
            else
            {
                ArrayList existingInventoryDataList = null;
                if( map.isEmpty() == false)
    	        {
                    existingInventoryDataList = ( ArrayList ) map.get( request.getParameter( "lineItemId" ) );
                    if( existingInventoryDataList != null )
                    {
                        mergeExistingInventoryDataListIntoFinalList ( finalInventoryDataList , existingInventoryDataList  );
                        map.put ( request.getParameter( "lineItemId" ), finalInventoryDataList );
                    }
                    else
                    {
                       map.put ( request.getParameter( "lineItemId" ), finalInventoryDataList );
                    }
                }
            }

			session.setAttribute( SessionKeys.FINAL_INVENTORY_MAP, map );

			session.removeAttribute ( "finalInventoryDataList" );
			session.removeAttribute ( "csLotNumberDataMap" );
			// This is required to close the window After saving the values
			request.setAttribute    ( "closeWindow", "true" );

			if( ( request.getParameter( "dropShip" ) ).equalsIgnoreCase( "true" ) )
			{
				return ( mapping.findForward ( "dropShipment" ) );
			}
			else
			{
				return ( mapping.findForward ( "success" ) );
			}
		}

		// VIEW ///////////////////////////////////////////////
		String partNumber 		    = request.getParameter ( "partNumber" );
        String parentPartNo         = request.getParameter ("parentPartNo");
		String lineItemId 		    = request.getParameter ( "lineItemId" );
		String viewonly 		    = request.getParameter ( "viewonly" );
		String vendorAddressId      = request.getParameter ( "shippingFromAddressId" );
		String dropShip			    = request.getParameter ( "dropShip" );
		String vendorLocation	    = null;
        String substitutePartNos    = request.getParameter ( "substitutePSIds" );
        String substitutePSIds      = FinalInventoryDAO.getProcessStepIdsAsString( substitutePartNos );
        boolean parentPartNoExitsInSubstitutables = false;

        String[]  substitutePartNoList = substitutePartNos.split(",");
        parentPartNoExitsInSubstitutables = isPartNoExistInSubstitutePartNoList ( parentPartNo, substitutePartNoList );

		long quantityToBeShipped = -1;

		try
		{
			quantityToBeShipped = Long.parseLong ( request.getParameter ( "quantityToBeShipped" ) );
		}
		catch (NumberFormatException nfe) {}

		String csLineItemId = request.getParameter( "csLineItemId" );

		long requestedQty = 0;
		try
		{
			requestedQty = Long.parseLong( request.getParameter ( "requestedQty" ) );
		}
		catch( NumberFormatException nfe )
		{
			//nfe.printStackTrace();
		}

		if( session.getAttribute( "repetedPartNumber"  ) != null )
		{
			ArrayList repeatingLineItems = (ArrayList) session.getAttribute( "repetedPartNumber" );
		}

		ArrayList finalInventoryDataList = FinalInventoryDAO.loadFinalInventoryDataByPartNumberAndLineItem( partNumber, lineItemId, csLineItemId, vendorAddressId, substitutePSIds );

		if( ( finalInventoryDataList != null ) && ( finalInventoryDataList.isEmpty() == false ) )
		{
			HashMap existingFinalInventoryDataListMap = (HashMap) session.getAttribute( SessionKeys.FINAL_INVENTORY_MAP );

			if( dropShip != null && dropShip.equalsIgnoreCase( "true" ) )
			{
				vendorLocation = VendorDAO.getLocationByAddressId( Integer.parseInt( vendorAddressId ), Constants.LOCATION_TYPE_FINISHED_GOODS );
				setNewDropShipLotsToFinalInventoryDataList( lineItemId, finalInventoryDataList, existingFinalInventoryDataListMap, vendorAddressId, vendorLocation, parentPartNoExitsInSubstitutables, substitutePartNoList );
			}

			if( ( existingFinalInventoryDataListMap != null ) && ( existingFinalInventoryDataListMap.isEmpty() == false ) )
			{
				ArrayList existingFinalInventoryDataList = ( ArrayList ) existingFinalInventoryDataListMap.get( lineItemId );
				if( ( existingFinalInventoryDataList != null ) && ( existingFinalInventoryDataList.isEmpty() == false ) )
				{
					FinalInventoryData finalInventoryData = null;
					HashMap lotIdAndFinalInventoryDataListMap = buildLotIdAndFinalInventoryDataListMap( existingFinalInventoryDataList );
					Iterator finalInventoryDataListIterator = finalInventoryDataList.iterator();
					FinalInventoryData existingFinalInventoryData = null;

					while( finalInventoryDataListIterator.hasNext() )
					{
						finalInventoryData = ( FinalInventoryData ) finalInventoryDataListIterator.next();

                        // in Drop Shippment the LotId is -1 for all the new Lots
						// if( finalInventoryData.getBalance() >= 0 )
						if ( finalInventoryData.getBalance() >= 0 && finalInventoryData.getLotId() != -1 )
						{
                            if( lotIdAndFinalInventoryDataListMap.containsKey( finalInventoryData.getLotId() + "" ) )
                            {
							    existingFinalInventoryData = ( FinalInventoryData ) lotIdAndFinalInventoryDataListMap.get( finalInventoryData.getLotId()+"" );
                                int prevQtyPull = 0;
                                if( finalInventoryData.getQuantityPull() > 0 )
                                    prevQtyPull = finalInventoryData.getQuantityPull();
                                finalInventoryData.setQuantityPull( existingFinalInventoryData.getQuantityPull() );
                                if( session.getAttribute( "repetedPartNumber" ) != null )
                                {
                                    finalInventoryData.setBalance( finalInventoryData.getBalance() -  existingFinalInventoryData.getQuantityPull() );
                                }
                                else
                                {
                                    finalInventoryData.setBalance( finalInventoryData.getBalance() -  existingFinalInventoryData.getQuantityPull() + prevQtyPull );
                                }
                            }
                            else
                            {
                                finalInventoryData.setQuantityPull( 0 );
                            }
						}
					}
				}
			}
		}
		else if ( ( ( finalInventoryDataList == null ) || ( finalInventoryDataList.isEmpty() == true ) ) &&  dropShip != null && dropShip.equalsIgnoreCase( "true" ) )
		{
			finalInventoryDataList = new ArrayList();
			HashMap existingFinalInventoryDataListMap = (HashMap) session.getAttribute( SessionKeys.FINAL_INVENTORY_MAP );
			if( existingFinalInventoryDataListMap != null  )
			if( dropShip != null && dropShip.equalsIgnoreCase( "true" ) )
			{
				vendorLocation = VendorDAO.getLocationByAddressId( Integer.parseInt( vendorAddressId ), Constants.LOCATION_TYPE_FINISHED_GOODS );
				setNewDropShipLotsToFinalInventoryDataList( lineItemId, finalInventoryDataList, existingFinalInventoryDataListMap, vendorAddressId, vendorLocation, parentPartNoExitsInSubstitutables, substitutePartNoList);
			}
		}

		HashMap orgFinalInventoryDataListMap = null;

		if( ( finalInventoryDataList != null ) && ( finalInventoryDataList.isEmpty() == false ) )
		{
			if( request.getParameter("openOrIssued") != null && request.getParameter("openOrIssued").equals("loadSalesOrder") )
			{
				if( session.getAttribute("repetedPartNumber")!= null )
				{
					ArrayList repeatingLineItems = (ArrayList) session.getAttribute( "repetedPartNumber" );
					if(repeatingLineItems.contains(lineItemId+""))
					{
						HashMap existingFinalInventoryDataListMap = (HashMap) session.getAttribute( SessionKeys.FINAL_INVENTORY_MAP );
						for(int i=0 ; i < repeatingLineItems.size() ; i++)
						{
							if( !repeatingLineItems.get(i).equals(lineItemId+"") )
							{
								if( existingFinalInventoryDataListMap != null && existingFinalInventoryDataListMap.size() > 0 ){
									ArrayList existingFinalInventoryDataList = ( ArrayList ) existingFinalInventoryDataListMap.get( repeatingLineItems.get(i) );
									if( ( existingFinalInventoryDataList != null ) && ( existingFinalInventoryDataList.isEmpty() == false ) )
									{
										HashMap lotIdAndFinalInventoryDataListMap = buildLotIdAndFinalInventoryDataListMap( existingFinalInventoryDataList );
										Iterator finalInventoryDataListIterator = finalInventoryDataList.iterator();
										FinalInventoryData finalInventoryData = null;
										FinalInventoryData existingFinalInventoryData = null;

										while( finalInventoryDataListIterator.hasNext() )
										{
											finalInventoryData = ( FinalInventoryData ) finalInventoryDataListIterator.next();
											if(lotIdAndFinalInventoryDataListMap.containsKey(finalInventoryData.getLotId()+""))
											{
												int pullQty = ((FinalInventoryData)lotIdAndFinalInventoryDataListMap.get(finalInventoryData.getLotId()+"")).getQuantityPull();
												if( pullQty > 0 )
												{
													finalInventoryData.setBalance(finalInventoryData.getBalance()- pullQty );
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			else if( request.getParameter("openOrIssued") != null && request.getParameter("openOrIssued").equals("view"))
			{
				if( session.getAttribute("repetedPartNumber")!= null )
				{
					ArrayList repeatingLineItems = (ArrayList) session.getAttribute( "repetedPartNumber" );
					if(repeatingLineItems.contains(lineItemId+""))
					{
						if( session.getAttribute("orgFinalInventoryDataList") == null )
						{
							orgFinalInventoryDataListMap = new HashMap();
							orgFinalInventoryDataListMap.put( lineItemId , finalInventoryDataList );
							session.setAttribute("orgFinalInventoryDataList",orgFinalInventoryDataListMap);
						}
						else
						{
							orgFinalInventoryDataListMap = (HashMap) session.getAttribute("orgFinalInventoryDataList");
							if( !orgFinalInventoryDataListMap.containsKey( lineItemId ) )
							{
								orgFinalInventoryDataListMap.put( lineItemId , finalInventoryDataList );
								session.setAttribute("orgFinalInventoryDataList",orgFinalInventoryDataListMap);
							}
						}
						HashMap existingFinalInventoryDataListMap = (HashMap) session.getAttribute( SessionKeys.FINAL_INVENTORY_MAP );
						for(int i=0 ; i < repeatingLineItems.size() ; i++)
						{
							if( !repeatingLineItems.get(i).equals(lineItemId+"") )
							{
								if( existingFinalInventoryDataListMap != null && existingFinalInventoryDataListMap.size() > 0 )
								{
									ArrayList existingFinalInventoryDataList = ( ArrayList ) existingFinalInventoryDataListMap.get( repeatingLineItems.get(i) );
									if( ( existingFinalInventoryDataList != null ) && ( existingFinalInventoryDataList.isEmpty() == false ) )
									{
										HashMap lotIdAndFinalInventoryDataListMap = buildLotIdAndFinalInventoryDataListMap( existingFinalInventoryDataList );
										Iterator finalInventoryDataListIterator = finalInventoryDataList.iterator();
										FinalInventoryData finalInventoryData = null;
										FinalInventoryData existingFinalInventoryData = null;

										while( finalInventoryDataListIterator.hasNext() )
										{
											finalInventoryData = ( FinalInventoryData ) finalInventoryDataListIterator.next();
											if(lotIdAndFinalInventoryDataListMap.containsKey(finalInventoryData.getLotId()+""))
											{
												int pullQty = ((FinalInventoryData)lotIdAndFinalInventoryDataListMap.get(finalInventoryData.getLotId()+"")).getQuantityPull();
												if( pullQty > 0 )
												{
													finalInventoryData.setBalance(finalInventoryData.getBalance()- pullQty );
												}
											}
										}
									}
								}
							}
						}
						for(int i=0 ; i < finalInventoryDataList.size() ; i++ )
						{
							FinalInventoryData fid = (FinalInventoryData)finalInventoryDataList.get(i);
							int corrVal = checkExistingInOrginalData(orgFinalInventoryDataListMap, lineItemId, fid.getBalance(), fid.getLotId(), existingFinalInventoryDataListMap);
							fid.setBalance(fid.getBalance()+ corrVal );
						}
					}
				}

				HashMap existingFinalInventoryDataListMap = (HashMap) session.getAttribute( SessionKeys.FINAL_INVENTORY_MAP );
				if ( existingFinalInventoryDataListMap != null && existingFinalInventoryDataListMap.isEmpty() == false )
				{
					ArrayList existingFinalInventoryDataList = ( ArrayList ) existingFinalInventoryDataListMap.get( lineItemId );
					HashMap lotIdAndFinalInventoryDataListMap = buildLotIdAndFinalInventoryDataListMap( existingFinalInventoryDataList );
					Iterator finalInventoryDataListIterator = finalInventoryDataList.iterator();
					FinalInventoryData finalInventoryData = null;
					FinalInventoryData existingFinalInventoryData = null;

					while ( finalInventoryDataListIterator.hasNext() )
					{
						existingFinalInventoryData = ( FinalInventoryData ) finalInventoryDataListIterator.next();
						// Drop Shippment the LotId is -1 for all the new Lots
						// if( lotIdAndFinalInventoryDataListMap.containsKey(existingFinalInventoryData.getLotId()+"") )
						if( lotIdAndFinalInventoryDataListMap.containsKey(existingFinalInventoryData.getLotId()+"") && existingFinalInventoryData.getLotId() != -1)
						{
							int counts = finalInventoryDataList.size();
							for ( int initListCount=0; initListCount < counts; initListCount++ )
							{
								finalInventoryData = (FinalInventoryData)finalInventoryDataList.get(initListCount);
								if ( finalInventoryData.getLotId() == existingFinalInventoryData.getLotId() )
								{
									finalInventoryData.setBalance (existingFinalInventoryData.getBalance());
								}
							}
						}

                        if( existingFinalInventoryDataList != null && dropShip != null)  // SETTING THE REDUCE BALANCE CHECK BOX ..
                        {
                            FinalInventoryData tempFinalInvDat = null;
                            for ( int initListCount=0; initListCount < existingFinalInventoryDataList.size() ; initListCount++ )
                            {
                                tempFinalInvDat =  (FinalInventoryData) existingFinalInventoryDataList.get( initListCount );
                                if ( existingFinalInventoryData.getLotId() == tempFinalInvDat.getLotId() &&  existingFinalInventoryData.getLotNumber().equalsIgnoreCase( tempFinalInvDat.getLotNumber() )  )
                                {
                                    existingFinalInventoryData.setIsReduceBalance ( tempFinalInvDat.getIsReduceBalance() );
                                }
                            }
                        }
					}
				}
			}
		}

        FinalInventoryData inventoryData = null;
        if( ( finalInventoryDataList != null ) && ( finalInventoryDataList.isEmpty() == false ) )
        {
            int listSize = finalInventoryDataList.size();
            HashMap inValidLotsMap = new HashMap();
            for( int j = 0; j < listSize ; j++ )
            {
                inventoryData = ( FinalInventoryData ) finalInventoryDataList.get( j );
                if( isPartNoExistInSubstitutePartNoList ( inventoryData.getMktPartNumber() , substitutePartNoList ) == false )
                {
                    inValidLotsMap.put( inventoryData.getLotId() + "" , "");
                }
            }
            if( inValidLotsMap != null && inValidLotsMap.isEmpty() == false )
    	    {
                Iterator inValidLotNoIT = inValidLotsMap.keySet().iterator();
                FinalInventoryData invFIData = null;
                String inValidLotNo =  null;
                while( inValidLotNoIT.hasNext() )
                {
                    inValidLotNo	= (String) inValidLotNoIT.next();
                    for( int j = 0; j < finalInventoryDataList.size() ; j++ )
                    {
                        if(  finalInventoryDataList.get( j ) != null )
                        {
                            invFIData = ( FinalInventoryData ) finalInventoryDataList.get( j );
                            if( invFIData != null && inValidLotNo.equalsIgnoreCase( invFIData.getLotId() + "" ) && invFIData.getQuantityPull() <= 0 )
                            {
                                finalInventoryDataList.remove(j);
                            }
                        }
                    }
                }
            }
        }

		session.setAttribute( "finalInventoryDataList", finalInventoryDataList );
		request.setAttribute( "lineItemId", lineItemId );
		request.setAttribute( "quantityToBeShipped", quantityToBeShipped+"" );
		request.setAttribute( "requestedQty", requestedQty+"" );
		request.setAttribute( "viewOnly", viewonly );
        request.setAttribute( "parentPartNoExitsInSubstitutables" , parentPartNoExitsInSubstitutables + "");

		if( dropShip.equalsIgnoreCase( "true" ) )
		{
			return ( mapping.findForward ( "dropShipment" ) );
		}
		else
		{
			return ( mapping.findForward ( "success" ) );
		}
	}

	 /**
     * @param finalInventoryDataList
     * @param existingFinalInventoryDataListMap
     */
    private void setNewDropShipLotsToFinalInventoryDataList( String lineItemId, ArrayList finalInventoryDataList, HashMap existingFinalInventoryDataListMap, String vendorAddressId, String vendorLocation, boolean parentPartNoExitsInSubstitutables, String[] substitutePartNoList )
    {
    	ArrayList existingFinalInventoryDataList = null;
		FinalInventoryData existingInventoryData = null;
		FinalInventoryData inventoryData 		 = null;
		int vendorLocationId					 = -1;
		String vendorLocationName				 = null;
		boolean newLot 							 = false;
    	if( existingFinalInventoryDataListMap != null && existingFinalInventoryDataListMap.isEmpty() == false )
    	{
			existingFinalInventoryDataList = ( ArrayList ) existingFinalInventoryDataListMap.get( lineItemId );
			if( existingFinalInventoryDataList != null && existingFinalInventoryDataList.isEmpty() == false )
			{
				for( int i = 0; i < existingFinalInventoryDataList.size(); i++ )
				{
					newLot = false;
					existingInventoryData = ( FinalInventoryData ) existingFinalInventoryDataList.get( i );
					if( finalInventoryDataList.isEmpty() == false )
					{
						for( int j = 0; j < finalInventoryDataList.size(); j++ )
						{
							inventoryData = ( FinalInventoryData ) finalInventoryDataList.get( j );
							if( existingInventoryData.getLotId() == -1 && inventoryData.getLotNumber().equalsIgnoreCase( existingInventoryData.getLotNumber() ) )
							{
								break;
							}
							else if( existingInventoryData.getLotId() == -1 && parentPartNoExitsInSubstitutables == true  )
							{
								newLot = true;
							}
						}
					}
					else
					{
                        if( isPartNoExistInSubstitutePartNoList ( existingInventoryData.getMktPartNumber() , substitutePartNoList ) )
                        {
						    newLot = true;
                        }
					}
					if( newLot )
					{
                        finalInventoryDataList.add( new FinalInventoryData( existingInventoryData.getCsLineItemId(),
																			existingInventoryData.getMktPartNumber(),
																			existingInventoryData.getLotNumber(),
																			existingInventoryData.getFabLotNumber(),
																			existingInventoryData.getLotId(),
																			Integer.parseInt( vendorAddressId ),
																			vendorLocation,
																			existingInventoryData.getDateCode(),
																			Constants.LOCATION_TYPE_FINISHED_GOODS,
																			existingInventoryData.getDateIn(),
																			existingInventoryData.getQuantityIn(),
																			existingInventoryData.getBalance(),
																			0,
																			existingInventoryData.getQuantityPull() ) )	;
					}
				}
			}
    	}
        //System.out.println("--------------------------------------------------------------------------------------------");
    }


    /* This method will check for the balance modifications in final inventory
	 in case of multiple line items with the same part numbers.
	 */
	private int checkExistingInOrginalData(HashMap orgFinalInventoryDataListMap, String lineItemId, int balance, int lotId, HashMap existingMap)
	{
		int value = 0;
		int pullQty = 0;
		Object[] lineItemKeys = (Object[]) orgFinalInventoryDataListMap.keySet().toArray();

		if( orgFinalInventoryDataListMap != null && orgFinalInventoryDataListMap.size() > 0 && existingMap !=null && existingMap.size() > 0 )
        {
			for( int i=0 ; i < lineItemKeys.length ; i++ )
			{
				String orgLineItemId = ( String )lineItemKeys[i];
				ArrayList orgFinalInventoryDataList = ( ArrayList )orgFinalInventoryDataListMap.get( orgLineItemId );
				ArrayList existingFinalInventoryDataList = ( ArrayList ) existingMap.get( orgLineItemId );
				HashMap lotIdAndFinalInventoryDataListMap = buildLotIdAndFinalInventoryDataListMap( existingFinalInventoryDataList );

				for( int j=0 ; j < orgFinalInventoryDataList.size() ; j++)
				{
					FinalInventoryData orgFinalInventoryData = (FinalInventoryData)orgFinalInventoryDataList.get(j);
					if( orgFinalInventoryData.getLotId() == lotId  )
					{
						if( orgFinalInventoryData.getQuantityPull() > 0 )
						{
							if(lotIdAndFinalInventoryDataListMap.containsKey(orgFinalInventoryData.getLotId()+""))
							{
								pullQty = ((FinalInventoryData)lotIdAndFinalInventoryDataListMap.get(orgFinalInventoryData.getLotId()+"")).getQuantityPull();
								value = value + orgFinalInventoryData.getQuantityPull(); //+(orgFinalInventoryData.getQuantityPull()-pullQty);//-pullQty;
							}
						}
					}
				}
			}
		}
		return value;
	}

	private ArrayList getFinalInventoryDataFromRequest ( HttpServletRequest request ) throws Exception
	{
		ArrayList inventoryDataList = new ArrayList();
		boolean success 			= false;
		int totQuantityPulled 		= 0;
		String[] lotIds 			= request.getParameterValues("lotId");

		if ( ( lotIds == null ) || ( lotIds.length == 0 ) )
		{
			return inventoryDataList;
		}

		String[] csLineItemIds 	= request.getParameterValues ( "csLineItemId" );
		String[] mktPartNumbers = request.getParameterValues ( "mktPartNumber" );
		String[] quantityPulled = request.getParameterValues ( "quantityToPull" );
		String[] balance 		= request.getParameterValues ( "balance" );
		String[] lotNumbers 	= request.getParameterValues ( "lotNumber" );
		String[] dateCode 		= request.getParameterValues ( "dateCode" );
		String[] dateIn	 		= request.getParameterValues ( "dateIn" );
		String[] qtyIn			= request.getParameterValues ( "hdnQuantityIn" );
		String[] locationId		= request.getParameterValues ( "locationId" );
        String[] isReduceBal	= request.getParameterValues ( "isReduceBal" );
        String[] fabLotNumber	= request.getParameterValues ( "fabLotNumber" );
        String[] dateCode1	    = request.getParameterValues ( "dateCode1" );
        int idForNewRow = -1;
		try
		{
			idForNewRow = Integer.parseInt( request.getParameter( "actualCsLineItemId" ) );
		}
		catch( NumberFormatException nfe )
		{
			// invalid cslit id
		}

		FinalInventoryData inventoryData = null;
		for ( int i = 0; i < lotIds.length; i++ )
		{
			int csLineItemId        = -1;
			int quantityPull        = 0;
			int lotId 		        = -1;
			int balanceVal          = -1;
			int quantityIn	        = 0;
			Date dt 		        = null;
            int isReduceBalance 	= -1;
			inventoryData = new FinalInventoryData();

			try
			{
				csLineItemId = Integer.parseInt( csLineItemIds[i] );
			}
			catch ( NumberFormatException nfe )   // no csLineItemID
			{
				inventoryData.setIdForNewRow( idForNewRow );
			}

			try
			{
				quantityPull = Integer.parseInt (quantityPulled[i]);
			}
			catch ( NumberFormatException nfe )
			{
				/* Zero quantity */
			}

			try
			{
				quantityIn = Integer.parseInt ( qtyIn[i] );
			}
			catch ( NumberFormatException nfe )
			{
				/* Zero quantity */
			}

			// Dont add this one, if no quantity pulled
			if ( quantityPull == 0 )
			{
				//continue;
			}

			// ALL VALIDITY CHECKS ARE DONE IN THE JSP ITSELF USING JAVASCRIPT
			// DONT THROW ANY EXCEPTION FROM HERE

			try
			{
				lotId = Integer.parseInt ( lotIds[i] );
				success = true;
			}
			catch (NumberFormatException nfe) {
				////system.out.println ("Invalid value for lotID, in the Quantity Pull window: " + lotIds[i]);
			}

			try
			{
				SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd" );
				dt 	= sdf.parse( dateIn[i] );
			}
			catch( Exception e )
			{
				dt = null;
			}

			// Date is parsed twice as the date formats are coming in two Different formats
			// one for common PS and one for DropShip new lots.
			if( dt == null )
			{
				try
				{
					SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy" );
					dt = sdf.parse( dateIn[i] );
				}
				catch( Exception e )
				{
					dt = null;
				}
			}

			try
			{
				balanceVal = Integer.parseInt ( balance[i] );
				success = true;
			}
			catch ( NumberFormatException nfe )
			{
				////system.out.println ("Invalid balance, in the Quantity Pull window, for lotID: " + lotId);
			}


           if( isReduceBal != null && isReduceBal[i] != null && isReduceBal[i].trim().length() > 0 && isReduceBal[i].equalsIgnoreCase("reduceBalance") )
           {
               isReduceBalance = 0;
           }
           else
           {
               isReduceBalance = 1;
           }


			if ( success == false )
			{
				continue;
			}
			else
			{
				success = false;
			}
			if( lotNumbers[i] != null && lotNumbers[i].length() > 0 )
			{
                inventoryData.setCsLineItemId( csLineItemId );
				inventoryData.setLotId( lotId );
				inventoryData.setBalance( balanceVal );
				inventoryData.setLotNumber( lotNumbers[i] );
				inventoryData.setMktPartNumber( mktPartNumbers[i] );
				inventoryData.setQuantityPull( quantityPull );

                if ( dateCode[i] != null )
                {
				    inventoryData.setDateCode( "0".equalsIgnoreCase(dateCode[i]) ? dateCode1[i] : dateCode[i] );
                }
                                
				inventoryData.setDateIn( dt );
				inventoryData.setQuantityIn( quantityIn );
				inventoryData.setLocationId( Integer.parseInt( locationId[i] ) );
                inventoryData.setIsReduceBalance( isReduceBalance );
                
                try
                {
                if( lotId == -1 )
				{
					if( quantityIn > 0 )
					{
                        inventoryData.setLotEnteredBy("0");// this lot belong's to DataEntry
                        if(fabLotNumber[i] == null || fabLotNumber[i].trim().length() == 0)
                        {
                            inventoryData.setFabLotNumber(inventoryData.getLotNumber());
                        }
                        else
                        {
                            inventoryData.setFabLotNumber( fabLotNumber[i] );
                        }
                        inventoryDataList.add ( inventoryData );
					}
				}
				else
				{
                    if( inventoryData.getFabLotNumber() == null || inventoryData.getFabLotNumber().trim().length() == 0 )
                    {
                        inventoryData.setFabLotNumber( inventoryData.getLotNumber() );
                    }
                    inventoryDataList.add ( inventoryData );
				}
                }
                catch( Exception e)
                {
                    inventoryData.setFabLotNumber( inventoryData.getLotNumber() );
                }
            }
		}
		return inventoryDataList;
	}
	private HashMap buildLotIdAndFinalInventoryDataListMap( ArrayList finalInventoryDataList )
	{
		HashMap lotIdAndFinalInventoryDataListMap = new HashMap();
		if( ( finalInventoryDataList == null ) || ( finalInventoryDataList.isEmpty() == true ) )
		{
			return lotIdAndFinalInventoryDataListMap;
		}

		Iterator finalInventoryDataListIterator = finalInventoryDataList.iterator();
		FinalInventoryData finalInventoryData = null;

		while( finalInventoryDataListIterator.hasNext() )
		{
			finalInventoryData = ( FinalInventoryData ) finalInventoryDataListIterator.next();
			lotIdAndFinalInventoryDataListMap.put( finalInventoryData.getLotId()+"", finalInventoryData );
		}

		return lotIdAndFinalInventoryDataListMap;
	}

	private ArrayList getLotIdNumberDetailsFromLocationIdMap (HashMap lotsByPartNumAndLocationMap )
	{
		ArrayList lotIdLotNumberDetails = new ArrayList();
		Set locationKeys = lotsByPartNumAndLocationMap.keySet();
		Object[] arrayLocationKey =  locationKeys.toArray();

		FinalInventoryData finalInventoryData = new FinalInventoryData();
		ArrayList lotDetails = null;
		for (int count=0; count < arrayLocationKey.length; count++)
		{
			String locationKey = arrayLocationKey[count].toString();
			if (lotsByPartNumAndLocationMap.containsKey (locationKey) == true)
			{
				lotDetails = (ArrayList)lotsByPartNumAndLocationMap.get(locationKey);
				for (int lotDetailsCount = 0; lotDetailsCount < lotDetails.size(); lotDetailsCount++ )
				{
					lotIdLotNumberDetails.add(lotDetails.get(lotDetailsCount));
				}
			}
		}
		return lotIdLotNumberDetails;
	}

    private boolean isPartNoExistInSubstitutePartNoList (String partNumber, String[] substitutePartNoList  )
	{
        boolean partNoExitsInSubstitutables = false;
        if( substitutePartNoList != null && substitutePartNoList.length > 0  )
        {
            for(int idx = 0; idx < substitutePartNoList.length ; idx++ )
            {
                if( partNumber.equalsIgnoreCase( substitutePartNoList[idx] ) )
                {
                    partNoExitsInSubstitutables = true;
                    break;
                }
            }
        }
		return partNoExitsInSubstitutables;
	}
    public static void mergeExistingInventoryDataListIntoFinalList ( ArrayList finalInventoryDataList , ArrayList existingFinalInventoryDataList)
    {
        FinalInventoryData existingFIData   = null;
        FinalInventoryData finalFIData      = null;
        int existingListSize                = 0;
        int finalListSize                   = 0;
        HashMap missedLotNumbersMap         = new HashMap();

        existingListSize = existingFinalInventoryDataList.size();
        finalListSize = finalInventoryDataList.size();

        if( finalInventoryDataList != null && finalInventoryDataList.size() > 0 &&   existingFinalInventoryDataList != null && existingFinalInventoryDataList.size() > 0 )
        {
            for ( int j = 0; j < existingListSize; j++ )
            {
                existingFIData = ( FinalInventoryData ) existingFinalInventoryDataList.get( j );
                missedLotNumbersMap.put( existingFIData.getLotId() + "" , "" );
            }
            for ( int i = 0; i < finalListSize; i++ )
            {
               finalFIData = ( FinalInventoryData ) finalInventoryDataList.get( i );
               if( missedLotNumbersMap.containsKey( finalFIData.getLotId() + "" ) )
               {
                    missedLotNumbersMap.remove( finalFIData.getLotId() + "" );
               }
            }
            Iterator missedLotNoIT = missedLotNumbersMap.keySet().iterator();
            String missedLotNo =  null;
            while( missedLotNoIT.hasNext() )
            {
                missedLotNo	= (String) missedLotNoIT.next();
                for ( int j = 0; j < existingListSize; j++ )
                {
                    existingFIData = ( FinalInventoryData ) existingFinalInventoryDataList.get( j );
                    if( missedLotNo.equalsIgnoreCase( existingFIData.getLotId() + "" ) )
                    {
                        finalInventoryDataList.add(existingFIData);
                    }
                }
            }
        }
    }
}